import type {
  IShape,
  IGroup,
  ModelConfig,
  Item,
  INode,
  IEdge,
  G6GraphEvent,
} from "@antv/g6";
import G6 from "@antv/g6";
import { _getImg, _formatDate, _diffDays } from "./utils";

const _actualWarningTime = 1111;

export default class processG6 {
  public isTemplate: boolean = false;

  public taskDefaultSize: Number[] = [298, 129];

  public setIsTemplate(value: boolean): void {
    this.isTemplate = value;
    this.taskDefaultSize = value ? [298, 129] : [298, 159];
  }

  /**
   * @author: 睡衣船长
   * @description: 创建普通任务卡片
   * @param {TaskModelConfig} cfg
   * @param {IGroup} group
   */
  public createTaskNode(cfg: any, group: IGroup): IShape {
    console.log(cfg.data, "任务数据画任务数据");
    //这里除了任务名称其他的尺寸和位置只是先占位，在afterDraw中会重新计算位置
    const size = cfg.size || this.taskDefaultSize; // 如果没有 size 时的默认大小
    // 任务状态
    this.addStatus(cfg.data, group, size);
    const keyShape = group.addShape("rect", {
      attrs: {
        x: -size[0] / 2,
        y: -size[1] / 2,
        width: size[0],
        height: size[1],
        fill: cfg.data.status == 3 ? "#F4F6F9" : "#ffffff",
        radius: 12,
        cursor: "pointer",
        shadowOffsetX: 0,
        shadowOffsetY: 10,
        shadowColor: "rgba(56, 71, 109, 0.06)",
        shadowBlur: 35,
        lineWidth: 2,
      },
      name: "task-rect-shape",
    });
    // 序号
    // const taskType = this.nowMilestoneId.value ? cfg.data.milestoneTaskType : cfg.data.taskType
    group.addShape("text", {
      attrs: {
        text: `阶段:${cfg.data.stage?.stageName || "无"}   ${
          cfg.data.stage?.groupNum
            ? "编号:" + cfg.data.stage.groupNum + "-" + cfg.data.stage.sortNum
            : ""
        }`,
        x: 16 - size[0] / 2,
        y: 16 - size[1] / 2,
        fontSize: 12,
        fontWeight: 500,
        textAlign: "left",
        textBaseline: "top",
        fill: cfg.data.status == 3 ? "#009ef780" : "#009ef7",
        cursor: "pointer",
      },
      name: "task-sort",
    });
    // 任务名称
    group.addShape("text", {
      attrs: {
        text: this.fittingString(cfg.data.taskName || "", size[0] - 52, 16),
        x: 16 - size[0] / 2,
        y: 40 - size[1] / 2,
        fontSize: 16,
        fontWeight: 500,
        textAlign: "left",
        textBaseline: "top",
        fill: "#181C32",
        cursor: "pointer",
      },
      name: "task-name-text-shape",
    });

    //第二行计划天数和实际天数的y值
    const secondY = 68;
    if (!this.isTemplate) {
      //只有在详情才画计划天数和实际天数
      group.addShape("text", {
        name: "task-plan-text",
        attrs: {
          text: "计划",
          x: 16 - size[0] / 2,
          y: secondY - size[1] / 2,
          fontSize: 14,
          textBaseline: "top",
          fill: "#A1A5B7",
        },
      });
      //计划天数
      group.addShape("text", {
        name: "task-plan-days",
        attrs: {
          text: cfg.data.taskDay + "天",
          x: 46 - size[0] / 2,
          y: secondY - size[1] / 2,
          fontSize: 14,
          fontWeight: 500,
          textBaseline: "top",
          fill: cfg.data.status == 3 ? "#A1A5B7" : "#5E6278",
        },
      });
      //分割线
      group.addShape("rect", {
        name: "plan-split-line",
        attrs: {
          x: 82 - size[0] / 2,
          y: secondY - size[1] / 2,
          width: 0.5,
          height: 12,
          stroke: "#EFF2F5",
        },
      });

      group.addShape("text", {
        name: "task-actual-text",
        attrs: {
          text: "实际",
          x: 94 - size[0] / 2,
          y: secondY - size[1] / 2,
          fontSize: 14,
          textBaseline: "top",
          fill: "#A1A5B7",
        },
      });
      //实际天数
      group.addShape("text", {
        name: "task-actual-days",
        attrs: {
          text: (Number(cfg.data?.actualTaskDay) / 24).toFixed(1) + "天",
          x: 126 - size[0] / 2,
          y: secondY - size[1] / 2,
          fontSize: 14,
          fontWeight: 500,
          textBaseline: "top",
          fill:
            cfg.data.isOverDue == 1
              ? "#F1416C"
              : cfg.data.status == 3
                ? "#A1A5B7"
                : "#5E6278",
        },
      });
    }

    //第三行任务部门和执行人的y值（模板应该是第二行，但是这里统称第三行）
    const thirdY = this.isTemplate ? 65 : 95;
    //第三行文本的y值
    const thirdTextY = thirdY + 3;

    // 部门图标
    group.addShape("image", {
      name: "task-executor-department-icon",
      attrs: {
        width: 20,
        height: 20,
        x: 16 - size[0] / 2,
        y: thirdY - size[1] / 2,
        img: _getImg("gap-flow-executor-department-icon.png"),
        cursor: "pointer",
        opacity: cfg.data.status == 3 ? 0.4 : 1,
      },
    });
    // 部门名称
    group.addShape("text", {
      name: "task-department-name",
      attrs: {
        text: cfg.data.orgName || "无",
        x: 42 - size[0] / 2,
        y: thirdTextY - size[1] / 2,
        fontSize: 14,
        textBaseline: "top",
        fill: "#5E6278",
        cursor: "pointer",
      },
    });
    // 执行人图标
    group.addShape("image", {
      name: "task-executor-icon",
      attrs: {
        width: 20,
        height: 20,
        x: 42 - size[0] / 2,
        y: thirdY - size[1] / 2,
        img: _getImg("gap-flow-executor-icon.png"),
        cursor: "pointer",
        opacity: cfg.data.status == 3 ? 0.4 : 1,
      },
    });
    // 执行人名称
    group.addShape("text", {
      name: "task-executor-name",
      attrs: {
        text: cfg.data.executorName || "无",
        x: 42 - size[0] / 2,
        y: thirdTextY - size[1] / 2,
        fontSize: 14,
        textBaseline: "top",
        fill: "#5E6278",
        cursor: "pointer",
      },
    });

    //第四行时间和子任务的y值（模板应该是第三行，但是这里统称第四行）
    const fourY = this.isTemplate ? 95 : 125;
    //第四行文本y值
    const fourTextY = fourY + 5;

    // 时间
    let timeBgWidth = 125;
    let timeText = cfg.data.startTime
      ? _formatDate(cfg.data.startTime, "MM月dd日") +
        "-" +
        _formatDate(cfg.data.endTime, "MM月dd日")
      : "未设置时间";
    // let timeText = cfg.data.startTime ? _formatDate(cfg.data.startTime, 'yyyy年MM月dd日') + '-' + _formatDate(cfg.data.endTime, 'yyyy年MM月dd日') : '未设置时间'
    if (cfg.data.startTime) {
      timeBgWidth = 200;
    }
    // 模板话时间计算出持续天数的宽度，然后设置
    if (this.isTemplate) {
      timeText = `持续时长:${cfg.data.taskDay || 0}天`;
    }
    // 时间背景
    group.addShape("rect", {
      name: "date-rect-shape",
      attrs: {
        x: 16 - size[0] / 2,
        y: fourY - size[1] / 2,
        width: timeBgWidth,
        height: 22,
        radius: 4,
        fill: "#F5F8FA",
        cursor: "pointer",
      },
    });
    group.addShape("text", {
      name: "date-time-shape",
      attrs: {
        text: timeText,
        x: timeBgWidth / 2 + 16 - size[0] / 2,
        y: fourTextY - size[1] / 2,
        fontSize: 12,
        fontWeight: 500,
        textAlign: "center",
        textBaseline: "top",
        fill: "#7E8299",
        cursor: "pointer",
      },
    });

    // 子任务数量背景实线
    group.addShape("rect", {
      name: "task-child-number-bg",
      attrs: {
        x: 224 - size[0] / 2,
        y: fourY - size[1] / 2,
        width: 58,
        height: 22,
        radius: 4,
        stroke: "#E4E6EF",
        cursor: "pointer",
      },
      visible: !!cfg.data.subTaskCount,
    });
    // 子任务图标
    group.addShape("image", {
      name: "task-count-icon",
      attrs: {
        width: 12,
        height: 12,
        x: 232 - size[0] / 2,
        y: fourTextY - size[1] / 2,
        img: _getImg("gap-flow-task-count-icon.png"),
        cursor: "pointer",
        opacity: 1,
      },
      visible: !!cfg.data.subTaskCount,
    });
    // 子任务数量情况
    group.addShape("text", {
      name: "task-count-text",
      attrs: {
        text:
          (cfg.data.finishSubTaskCount || 0) +
          "/" +
          (cfg.data.subTaskCount || 0),
        x: 252 - size[0] / 2,
        y: fourTextY - size[1] / 2,
        fontSize: 12,
        fontWeight: 500,
        textBaseline: "top",
        fill: "#7E8299",
        cursor: "pointer",
      },
      visible: !!cfg.data.subTaskCount,
    });
    // this.childTaskNumber.value = Number(this.childTaskNumber.value) + Number((cfg.data.subTaskCount || 0))

    // 任务类型图标
    // group.addShape('image', {
    //   name: 'task-type-icon',
    //   attrs: {
    //     width: 18,
    //     height: 18,
    //     x: 264 - size[0] / 2,
    //     y: 14 - size[1] / 2,
    //     // TODO
    //     img: _getImg(cfg.data.iconUrl || ''),
    //     cursor: 'pointer',
    //     opacity: cfg.data.status == 3 ? 0.4 : 1
    //   }
    // })

    //画临时新增标签
    if (!this.isTemplate && cfg.data.taskStyle == 1) {
      group.addShape("rect", {
        name: "temporary-add-bg",
        attrs: {
          x: -(size[0] / 2),
          y: -(size[1] / 2) - 10,
          width: 60,
          height: 20,
          radius: 4,
          fill: "#409eff",
        },
      });
      group.addShape("text", {
        name: "temporary-add-text",
        attrs: {
          text: "临时新增",
          x: 6 - size[0] / 2,
          y: 7 - size[1] / 2,
          fontSize: 12,
          fill: "#FFFFFF",
        },
      });
    }
    return keyShape;
  }

  /**
   * @author: 睡衣船长
   * @description: 给任务添加状态
   * @param {number} status
   * @param {IGroup} group
   * @param {number} size
   */
  private addStatus(data: any, group: IGroup, size: number[]) {
    const attrProps: any = {
      attrs: {
        x: -size[0] / 2,
        y: -size[1] / 2,
        width: size[0],
        height: size[1],
        fill: "#ffffff",
        radius: 12,
        cursor: "pointer",
        shadowOffsetX: 0,
        shadowOffsetY: -4,
        shadowColor: "#80a6ff",
        shadowBlur: 0,
      },
      name: "task-rect-status",
    };

    if (data.isOverDue == 1) {
      // 存在预计时间并且，任务实际开始小于计划开始
      const _sf = data.startTime
        ? "" + _formatDate(data.startTime, "yyyy-MM-dd") + " 00:00:00"
        : "";
      const _af = data.actualStartTime
        ? "" + _formatDate(data.actualStartTime, "yyyy-MM-dd") + " 00:00:00"
        : "";
      let _earlyTime = 0;
      if (_af && _sf && new Date(_af) < new Date(_sf)) {
        _earlyTime = _diffDays([_af, _sf]);
      }

      if (
        data.actualTaskDay <=
        Number(data.taskDay) + Number(_actualWarningTime) + _earlyTime
      ) {
        attrProps.attrs.shadowColor = "#ffd84e";
      } else {
        attrProps.attrs.shadowColor = "#ff7878";
      }
    } else {
      switch (data.status) {
        case 1:
          attrProps.attrs.shadowColor = "rgba(0, 194, 167, 0.3)";
          break;
        case 2:
          attrProps.attrs.shadowColor = "#80a6ff";
          break;
        case 3:
          attrProps.attrs.shadowColor = "#f8f7f7";
          break;
        default:
          attrProps.attrs.shadowColor = "#ffffff";
          break;
      }
    }

    group.addShape("rect", attrProps);
  }

  /**
   * @author: 睡衣船长
   * @description:
   * @param {string} str
   * @param {number} maxWidth
   * @param {number} fontSize
   * @return {*}
   */
  private fittingString(str: string, maxWidth: number, fontSize: number) {
    const ellipsis = "...";
    const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
    let currentWidth = 0;
    let res = str;
    // eslint-disable-next-line prefer-regex-literals
    const pattern = new RegExp("[\u4E00-\u9FA5]+"); // distinguish the Chinese charactors and letters
    str.split("").forEach((letter, i) => {
      if (currentWidth > maxWidth - ellipsisLength) return;
      if (pattern.test(letter)) {
        // Chinese charactors
        currentWidth += fontSize;
      } else {
        // get the width of single letter according to the fontSize
        currentWidth += G6.Util.getLetterWidth(letter, fontSize);
      }
      if (currentWidth > maxWidth - ellipsisLength) {
        res = `${str.substr(0, i)}${ellipsis}`;
      }
    });
    return res;
  }

  /**
   * @author: 睡衣船长
   * @description:
   * @param {TaskModelConfig} cfg
   * @param {IGroup} group
   * @return {*}
   */
  public afterDraw(cfg: any, group: IGroup) {
    const size = cfg.size || this.taskDefaultSize; // 如果没有 size 时的默认大小
    // console.log(this.isTemplate, this.isBindOrgLeader, gapFlowPageRoleLimits().templateSetting, '是否可以编辑是否可以编辑')
    // if (
    //   this.isTemplate
    //     ? (Number(this.userInfo.getOldUserInfo()?.roleId) == 2 || this.isBindOrgLeader.value || gapFlowPageRoleLimits().templateSetting)
    //     : (Number(this.userInfo.getOldUserInfo()?.roleId) == 2 || Number(this.manageUserId.value) == Number(this.userInfo.getOldUserInfo()?.id))) {
    // 添加任务图标非选中状态
    group.addShape("image", {
      attrs: {
        width: 24,
        height: 24,
        // x 和 y 分别减去 width / 2 与 height / 2，使矩形中心在 midPoint 上
        x: size[0] / 2 + 8,
        y: -12,
        img: _getImg("gap-flow-task-add-icon-no.png"),
        cursor: "pointer",
      },
      name: "add-new-task-btn-no",
      visible: false,
    });
    // 添加任务图标选中状态
    group.addShape("image", {
      attrs: {
        width: 24,
        height: 24,
        // x 和 y 分别减去 width / 2 与 height / 2，使矩形中心在 midPoint 上
        x: size[0] / 2 + 8,
        y: -12,
        img: _getImg("gap-flow-task-add-icon-yes.png"),
        cursor: "pointer",
      },
      name: "add-new-task-btn-yes",
      visible: false,
    });
    // 删除任务图标
    group.addShape("image", {
      name: "task-del-icon",
      attrs: {
        width: 24,
        height: 24,
        x: size[0] / 2 - 12,
        y: -size[1] / 2 - 12,
        img: _getImg("gap-flow-node-edge-remove-icon.png"),
        cursor: "pointer",
      },
      visible: false,
    });
    const children = group.get("children");
    const department_name = children.find(
      (child: { cfg: { name: string } }) =>
        child.cfg.name == "task-department-name"
    );
    const executorName = children.find(
      (child: { cfg: { name: string } }) =>
        child.cfg.name == "task-executor-name"
    );
    const width = department_name.getBBox().width;
    const executor_icon = children.find(
      (child: { cfg: { name: string } }) =>
        child.cfg.name == "task-executor-icon"
    );
    const executor_name = children.find(
      (child: { cfg: { name: string } }) =>
        child.cfg.name == "task-executor-name"
    );
    executor_icon.attrs.x =
      executor_icon.attrs.x + (width > 90 ? 90 : width) + 12;
    executor_name.attrs.x = executor_icon.attrs.x + 26;
    if (cfg.data.organizationId == 0) {
      executor_icon.attr("img", _getImg("gap-flow-executor-store-icon.png"));
      executor_icon.attr(
        "x",
        executor_icon.attr("x") + (width > 90 ? 90 : width)
      );
      executor_name.attr("x", executor_icon.attr("x") + 26);
      department_name.attr("text", "门店");
    }
    if (department_name.getBBox().width > 90) {
      department_name.attr(
        "text",
        this.fittingString(cfg.data.orgName || "无", 90, 14)
      );
    }
    if (executorName.getBBox().width > 150) {
      executorName.attr(
        "text",
        this.fittingString(cfg.data.executorName || "无", 150, 14)
      );
    }
    // if (cfg.data.status == 3) {
    //   this.setTaskOverStatus(group)
    // }

    //在详情在页面需要重新设置分割线和实际天数的左边距
    if (!this.isTemplate) {
      //获取计划天数文本的宽度，然后画分割线和实际天数
      const taskPlanTextWidth = children
        .find(
          (child: { cfg: { name: string } }) =>
            child.cfg.name == "task-plan-text"
        )
        ?.getBBox().width;
      const taskPlanDaysWidth = children
        .find(
          (child: { cfg: { name: string } }) =>
            child.cfg.name == "task-plan-days"
        )
        ?.getBBox().width;
      const planSplitLine = children.find(
        (child: { cfg: { name: string } }) =>
          child.cfg.name == "plan-split-line"
      );
      const taskActualText = children.find(
        (child: { cfg: { name: string } }) =>
          child.cfg.name == "task-actual-text"
      );
      const taskActualDays = children.find(
        (child: { cfg: { name: string } }) =>
          child.cfg.name == "task-actual-days"
      );
      //24 16+8
      planSplitLine.attr(
        "x",
        taskPlanTextWidth + taskPlanDaysWidth + 24 - size[0] / 2
      );
      //33 16+17
      taskActualText.attr(
        "x",
        taskPlanTextWidth + taskPlanDaysWidth + 33 - size[0] / 2
      );
      //65 16+49
      taskActualDays.attr(
        "x",
        taskPlanTextWidth + taskPlanDaysWidth + 65 - size[0] / 2
      );
    }

    const dateTimeShape = children.find(
      (child: { cfg: { name: string } }) => child.cfg.name == "date-time-shape"
    ); //时间文本
    const dateRectShape = children.find(
      (child: { cfg: { name: string } }) => child.cfg.name == "date-rect-shape"
    ); //时间文本背景
    const dateTimeShapeWidth = dateTimeShape.getBBox().width; //时间文本的宽度
    //更新时间文本的位置  22的意思（16（大卡片的左边距）+6（背景左内边距））
    dateTimeShape.attr("x", dateTimeShapeWidth / 2 + 22 - size[0] / 2);
    //更新时间的背景宽度
    dateRectShape.attr("width", dateTimeShapeWidth + 12);

    const dateRectShapeWidth = dateRectShape.getBBox().width; //时间背景的宽度

    // 重新设置子任务框宽度及坐标位置
    const subTaskCount = children.find(
      (child: { cfg: { name: string } }) => child.cfg.name == "task-count-text"
    );
    const subTaskCountWidth = subTaskCount.getBBox().width;
    const subTaskBg = children.find(
      (child: { cfg: { name: string } }) =>
        child.cfg.name == "task-child-number-bg"
    );
    const subTaskIcon = children.find(
      (child: { cfg: { name: string } }) => child.cfg.name == "task-count-icon"
    );
    //28意思  左右边距12 图标12 图标和文字间距4
    subTaskBg.attr("width", subTaskCountWidth + 28);
    //22意思   16（大卡片的左边距） 6(时间和子任务的间距)
    //28意思   16（大卡片的左边距） 6(时间和子任务的间距)  6(背景框的左内边距)
    //44意思   16（大卡片的左边距） 6(时间和子任务的间距)  6(背景框的左内边距) 12（图标宽度） 4（图标和数据间距）
    subTaskBg.attr("x", dateRectShapeWidth + 22 - size[0] / 2);
    subTaskIcon.attr("x", dateRectShapeWidth + 28 - size[0] / 2);
    subTaskCount.attr("x", dateRectShapeWidth + 44 - size[0] / 2);
  }

  /**
   * @author: 睡衣船长
   * @description:
   * @param {string} name
   * @param {string} value
   * @param {Item} item
   * @return {*}
   */
  public setState(name: string, value: string, item: Item) {
    // if (this.isTemplate) {
    //   this.projectAuth.value.listEditTask = this.projectAuth.value.processEditTask
    //   this.projectAuth.value.listDelTask = this.projectAuth.value.processDeleteTask
    // }
    const group = item.getContainer();
    const children = group.get("children");
    // const shape = children[1] // 顺序根据 draw 时确定
    const shape = item.getKeyShape();
    // console.log(group.get('children'), 'children')
    const model = item.getModel() as any;
    // console.log(model, 'model')
    // const isFirstTask = this.nowMilestoneId.value ? model.data.milestoneTaskType == 2 : model.data.taskType == 2
    // const isLastTask = this.nowMilestoneId.value ? model.data.milestoneTaskType == 3 : model.data.taskType == 3
    const isFirstTask = model.data.taskType == 2;
    const isLastTask = model.data.taskType == 3;
    if (!children) return;
    const delTask = children.find(
      (child: { cfg: { name: string } }) => child.cfg.name == "task-del-icon"
    );
    if (name == "active" && !item.hasState("selected")) {
      if (value) {
        if (
          !isFirstTask &&
          !isLastTask &&
          model.data.status != 3 &&
          model.data.status != 2
        ) {
          delTask?.show();
          delTask?.toFront();
        }
        shape.attr("stroke", "#409eff");
      } else {
        delTask?.hide();
        shape.attr("stroke", "");
      }
    }
    if (name == "selected") {
      const newBtnNo = children.find(
        (child: { cfg: { name: string } }) =>
          child.cfg.name == "add-new-task-btn-no"
      );
      if (value) {
        // if (
        //   !isFirstTask &&
        //   !isLastTask &&
        //   this.detail.value.tableStatus != 3 &&
        //   model.data.status != 2
        // ) {
        //   delTask?.show()
        // }
        shape.attr("stroke", "#409eff");
        // console.log(this.projectAuth.value.listEditTask, 'projectAuth.value.listEditTask', this.isManager)
        // if (
        //   !isLastTask &&
        //   this.detail.value.tableStatus != 3 &&
        //   model.data.status != 3
        // ) {
        //   // newLine && newLine.show()
        newBtnNo && newBtnNo.show() && newBtnNo.toFront();
        // }
      } else {
        delTask?.hide();
        shape.attr("stroke", "");
        // newLine && newLine.hide()
        newBtnNo && newBtnNo.hide();
      }
    }
    if (name == "createBtnHover") {
      const newBtnYes = children.find(
        (child: { cfg: { name: string } }) =>
          child.cfg.name == "add-new-task-btn-yes"
      );
      if (value && model.data.status != 3) {
        newBtnYes && newBtnYes.show() && newBtnYes.toFront();
      } else {
        newBtnYes && newBtnYes.hide();
      }
    }
    if (name == "create") {
      // if (value && this.detail.value.tableStatus != 3) {
      //   this._createTaskCtrl.setBeforeTaskId(model.id + '')
      //   this._createTaskCtrl.showDialog()
      // } else {
      //   this._createTaskCtrl.closeDialog()
      // }
    }
  }

  public setFlowerNodeHover(viewer: any) {
    viewer.on("node:mouseover", (ev: G6GraphEvent) => {
      const node = ev.item as INode;
      const model: any = node.getModel();
      if (
        ev?.target?.cfg?.name == "add-new-task-btn-no" ||
        ev?.target?.cfg?.name == "add-new-task-btn-yes"
      ) {
        node.setState("createBtnHover", true);
      } else {
        viewer.setItemState(node, "active", true);
        const edges = node.getEdges();
        edges.forEach((edge: IEdge) =>
          viewer.setItemState(edge, "running", true)
        );
      }
      // 子任务
      const subTaskShapeName = [
        "task-child-number-bg",
        "task-count-icon",
        "task-count-text",
      ];
      if (subTaskShapeName.includes(ev?.target?.cfg?.name)) {
        // 显示子任务
        // this.subTaskList.value = model.data.subTaskList || []
        // this.subTaskPanelParams.left = (ev?.target?.cfg?.canvasBBox?.x + 20) + 'px'
        // this.subTaskPanelParams.top = ev?.target?.cfg?.canvasBBox?.y + 'px'
        // this.subTaskPanelParams.height = (72 * (this.subTaskList.value.length <= 4 ? this.subTaskList.value.length : 4) + 5) + 'px'
        // this.subTaskPanelParams.panelVisible = true
      }
      // 显示任务全称
      if (ev?.target?.cfg?.name == "task-name-text-shape") {
        // ev?.target.attr('text', model.data.taskName)
        ev?.target.toFront();
      }
      const group = node.getContainer() as IGroup;
      const children = group.getChildren();
      // 执行人和对应图标变色
      if (model.data.status != 3) {
        if (
          ev?.target?.cfg?.name == "task-executor-name" ||
          ev?.target?.cfg?.name == "task-executor-icon"
        ) {
          // ev?.target.attr('text', model.data.executorName || '无')
          ev?.target.toFront();
          const text = children.find(
            (item) => item.cfg.name == "task-executor-name"
          );
          text && text.attr("fill", "#3F4254");
          const icon = children.find(
            (item) => item.cfg.name == "task-executor-icon"
          );
          if (model.data.organizationId == 0) {
            // ev?.target.attr('text', '门店')
            // if (this.projectAuth.value.listEditTask == 2) {
            // }
            icon &&
              icon.attr(
                "img",
                _getImg("gap-flow-executor-store-active-icon.png")
              );
          } else {
            // ev?.target.attr('text', model.data.orgName || '无')
            icon &&
              icon.attr("img", _getImg("gap-flow-executor-active-icon.png"));
          }
        }
      }
      // 部门和对应图标变色
      if (model.data.status != 3) {
        if (
          ev?.target?.cfg?.name == "task-department-name" ||
          ev?.target?.cfg?.name == "task-executor-department-icon"
        ) {
          console.log(model.data, "model.data");
          const text = children.find(
            (item) => item.cfg.name == "task-department-name"
          );
          text && text.attr("fill", "#3F4254");
          const icon = children.find(
            (item) => item.cfg.name == "task-executor-department-icon"
          );
          // if (this.projectAuth.value.listEditTask == 2) {
          // }
          // icon &&
          //   icon.attr(
          //     "img",
          //     _getImg("gap-flow-executor-department-active-icon.png")
          //   );
        }
      }
    });
    viewer.on("node:mouseout", (ev: G6GraphEvent) => {
      const node = ev.item as INode;
      const model: any = node.getModel();
      node.setState("createBtnHover", false);
      viewer.setItemState(node, "active", false);
      const edges = node.getEdges();
      edges.forEach((edge: IEdge) =>
        viewer.setItemState(edge, "running", false)
      );
      if (ev?.target?.cfg?.name == "task-rect-shape") {
        // this.subTaskPanelParams.panelVisible = false
        const group = node.getContainer() as IGroup;
        const children = group.getChildren();

        const text1 = children.find(
          (item) => item.cfg.name == "task-executor-name"
        );
        if (model.data.status != 3) {
          text1 && text1.attr("fill", "#5E6278");
        }
        const icon1 = children.find(
          (item) => item.cfg.name == "task-executor-icon"
        );
        if (model.data.organizationId == 0) {
          // ev?.target.attr('text', '门店')
          icon1 &&
            icon1.attr("img", _getImg("gap-flow-executor-store-icon.png"));
        } else {
          // ev?.target.attr('text', model.data.orgName || '无')
          icon1 && icon1.attr("img", _getImg("gap-flow-executor-icon.png"));
        }

        const text2 = children.find(
          (item) => item.cfg.name == "task-department-name"
        );
        if (model.data.status != 3) {
          text2 && text2.attr("fill", "#5E6278");
        }
        const icon2 = children.find(
          (item) => item.cfg.name == "task-executor-department-icon"
        );
        icon2 &&
          icon2.attr("img", _getImg("gap-flow-executor-department-icon.png"));
      }
      console.log(ev?.target?.cfg?.name, "ev?.target?.cfg?.name");
      const group = node.getContainer();
      const taskName = group.find(
        (item: { cfg: { name: string } }) =>
          item.cfg.name == "task-name-text-shape"
      );
      const bBox = node.getBBox();
      taskName.attr(
        "text",
        this.fittingString(model.data.taskName || "", bBox.width - 52, 16)
      );
      const executorName = group.find(
        (item: { cfg: { name: string } }) =>
          item.cfg.name == "task-executor-name"
      );
      executorName.attr(
        "text",
        this.fittingString(model.data.executorName || "无", 150, 14)
      );
      const departmentName = group.find(
        (item: { cfg: { name: string } }) =>
          item.cfg.name == "task-department-name"
      );
      departmentName.attr(
        "text",
        this.fittingString(
          model.data.orgName ||
            (model.data.organizationId == 0 ? "门店" : "无"),
          90,
          14
        )
      );
    });
    viewer.on("mouseover", (ev: G6GraphEvent) => {
      if (!ev.item) {
        // this.subTaskPanelParams.panelVisible = false
      }
    });
    // 增加画布拖动事件，记录canvas坐标
    // viewer.on('canvas:dragend', (ev: any) => {
    //   this.canvasPoint.x += ev.dx
    //   this.canvasPoint.y += ev.dy

    //   const left = Number(this._createTaskCtrl.taskEditParams.left.replace('px', ''))
    //   const top = Number(this._createTaskCtrl.taskEditParams.top.replace('px', ''))
    //   this._createTaskCtrl.setPosition((left + ev.dx) + 'px', (top + ev.dy) + 'px')

    //   const update_left = +this.updateTaskFloatRef.value.getPosition().left
    //   const update_top = +this.updateTaskFloatRef.value.getPosition().top
    //   this.updateTaskFloatRef.value.setPosition((update_left + ev.dx) + 'px', (update_top + ev.dy) + 'px')
    // })
    // viewer.on('wheel', (ev: any) => {
    //   const left = Number(this._createTaskCtrl.taskEditParams.left.replace('px', ''))
    //   const top = Number(this._createTaskCtrl.taskEditParams.top.replace('px', ''))
    //   this._createTaskCtrl.setPosition((left - ev.deltaX) + 'px', (top - ev.deltaY) + 'px')

    //   const update_left = +this.updateTaskFloatRef.value.getPosition().left
    //   const update_top = +this.updateTaskFloatRef.value.getPosition().top
    //   this.updateTaskFloatRef.value.setPosition((update_left - ev.deltaX) + 'px', (update_top - ev.deltaY) + 'px')
    // })
  }

  /**
   * @author: 睡衣船长
   * @description: 设置鼠标点击任务卡片事件
   */
  public setFlowerNodeClick(viewer: any) {
    // viewer.on('click', (ev: any) => {
    //   if (!ev?.item) {
    //     const nodes = viewer.getNodes()
    //     nodes.forEach((no: INode) => {
    //       no.setState('selected', false)
    //       this.reduceNodeWithEdge(no)
    //     })
    //     this.updateTaskFloatRef.value.showDialog()
    //   }
    // })
  }

  /**
   * @author: 睡衣船长
   * @description: 获取线路径
   * @param {TaskModelConfig} cfg
   */
  private getPath(cfg: any) {
    const startPoint = cfg.startPoint || { x: 0, y: 0 };
    const endPoint = cfg.endPoint || { x: 0, y: 0 };
    if (startPoint.y == endPoint.y) {
      return [
        ["M", startPoint.x, startPoint.y],
        ["L", endPoint.x, endPoint.y],
      ];
    } else if (startPoint.y < endPoint.y) {
      return [
        ["M", startPoint.x, startPoint.y],
        ["H", endPoint.x - 40],
        ["A", 20, 20, 0, 0, 1, endPoint.x - 30, startPoint.y + 20],
        ["V", endPoint.y - 20],
        ["A", 20, 20, 1, 0, 0, endPoint.x - 10, endPoint.y],
        ["L", endPoint.x, endPoint.y],
      ];
    } else {
      return [
        ["M", startPoint.x, startPoint.y],
        ["H", endPoint.x - 40],
        ["A", 20, 20, 1, 0, 0, endPoint.x - 30, startPoint.y - 20],
        ["V", endPoint.y + 20],
        ["A", 20, 20, 0, 0, 1, endPoint.x - 10, endPoint.y],
        ["L", endPoint.x, endPoint.y],
      ];
    }
  }

  /**
   * @author: 睡衣船长
   * @description: 自定义画线
   * @param {TaskModelConfig} cfg
   * @param {IGroup} group
   */
  public edgeDraw(cfg: any, group: IGroup): IShape {
    const keyShape = group.addShape("path", {
      attrs: {
        stroke: "#7da7f9",
        path: this.getPath(cfg),
        endArrow: {
          path: G6.Arrow.triangle(10, 10, 0),
          d: 0,
          fill: "#7da7f9",
        },
        lineWidth: 2,
      },
      name: "task-edge-path",
    });
    return keyShape;
  }

  /**
   * @author: 睡衣船长
   * @description: 画删除按钮
   * @param {TaskModelConfig} cfg
   * @param {IGroup} group
   */
  public edgeAfterDraw(cfg: any, group: IGroup) {
    const shape = group.get("children")[0];
    // 获取路径图形的中点坐标
    const midPoint0 = shape.getPoint(0);
    const midPoint1 = shape.getPoint(1);
    // 在中点增加一个矩形，注意矩形的原点在其左上角
    group.addShape("image", {
      attrs: {
        width: 16,
        height: 16,
        // x 和 y 分别减去 width / 2 与 height / 2，使矩形中心在 midPoint 上
        x: midPoint0.x + 7,
        y: midPoint0.y - 8,
        img: _getImg("gap-flow-node-edge-remove-icon.png"),
        cursor: "pointer",
      },
      visible: false,
      name: "remove-edge-image1", // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
    });
    group.addShape("image", {
      attrs: {
        width: 16,
        height: 16,
        // x 和 y 分别减去 width / 2 与 height / 2，使矩形中心在 midPoint 上
        x: midPoint1.x - 31,
        y: midPoint1.y - 8,
        img: _getImg("gap-flow-node-edge-remove-icon.png"),
        cursor: "pointer",
      },
      visible: false,
      name: "remove-edge-image2", // 在 G6 3.3 及之后的版本中，必须指定 name，可以是任意字符串，但需要在同一个自定义元素类型中保持唯一性
    });
  }

  /**
   * @author: 睡衣船长
   * @description: 设置线状态
   * @param {string} name
   * @param {string} value
   * @param {Item} item
   */
  public edgeSetState(name: string, value: string, item: IEdge) {
    // if (this.isTemplate.value) {
    //   this.projectAuth.value.listEditTask = this.projectAuth.value.processEditTask
    //   this.projectAuth.value.listDelTask = this.projectAuth.value.processDeleteTask
    // }
    const group = item.getContainer();
    if (!group.get("children")) return;
    const shape = group.get("children")[0]; // 顺序根据 draw 时确定
    console.log(name, "name", value);
    if (name === "activeIn") {
      const removeImage = group
        .get("children")
        .find(
          (child: { cfg: { name: string } }) =>
            child.cfg.name == "remove-edge-image1"
        );
      if (value) {
        shape.attr("lineWidth", 3);
        // if ((this.isManager) && this.detail.value.tableStatus != 3) {
        removeImage?.show();
        removeImage?.toFront();
        // }
      } else {
        shape.attr("lineWidth", 2);
        removeImage?.hide();
      }
    }
    if (name === "activeOut") {
      const removeImage = group
        .get("children")
        .find(
          (child: { cfg: { name: string } }) =>
            child.cfg.name == "remove-edge-image2"
        );
      if (value) {
        shape.attr("lineWidth", 3);
        // if ((this.isManager) && this.detail.value.tableStatus != 3) {
        removeImage?.toFront();
        removeImage?.show();
        // }
      } else {
        shape.attr("lineWidth", 2);
        removeImage?.hide();
      }
    }
    if (name === "running") {
      if (value) {
        item.toFront();
        item.getSource().toFront();
        shape.attr({
          stroke: "#1861f2",
          endArrow: {
            path: G6.Arrow.triangle(10, 10, 0),
            d: 0,
            fill: "#1861f2",
          },
          lineCap: "round",
        });
      } else {
        if (!item.hasState("activeIn") && !item.hasState("activeOut")) {
          item.toBack();
        }
        shape.attr({
          stroke: "#7da7f9",
          endArrow: {
            path: G6.Arrow.triangle(10, 10, 0),
            d: 0,
            fill: "#7da7f9",
          },
          lineCap: "round",
        });
      }
    }
  }

  /**
   * @author: 睡衣船长
   * @description: 处理节点相关联的线条上显示删除按钮
   * @param node
   */
  public reduceNodeWithEdge(node: any, viewer: any) {
    const edges = node.getEdges();
    const inEdges = node.getInEdges();
    const outEdges = node.getOutEdges();
    edges.forEach((edge: any) => {
      if (edge.getTarget()._cfg.id == node._cfg.id) {
        inEdges.push(edge);
      } else {
        outEdges.push(edge);
      }
    });
    //进行中的任务不能显示删除
    if (node.hasState("selected")) {
      inEdges.forEach((edge: any) => {
        const sourceNode = edge.getSource();
        const model = sourceNode.getModel() as any;
        const activeOutModel = edge.getTarget().getModel() as any;
        const nowTaskType = model.data.taskType;
        if (
          nowTaskType != 2 &&
          model.data.status != 2 &&
          activeOutModel.data.status != 2
        ) {
          viewer.setItemState(edge, "activeIn", true);
        }
      });
      outEdges.forEach((edge: any) => {
        const target = edge.getTarget();
        const model = target.getModel() as any;
        const activeInModel = edge.getSource().getModel();
        const nowTaskType = model.data.taskType;
        if (
          nowTaskType != 3 &&
          model.data.status != 2 &&
          activeInModel.data.status != 2
        ) {
          viewer.setItemState(edge, "activeOut", true);
        }
      });
      node.toFront();
    } else {
      inEdges.forEach((edge: IEdge) =>
        viewer.setItemState(edge, "activeIn", false)
      );
      outEdges.forEach((edge: IEdge) =>
        viewer.setItemState(edge, "activeOut", false)
      );
    }
  }
}
